package com.top.art.manager;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.top.art.bo.UserBO;
import com.top.art.bo.UserPageQueryBO;
import com.top.art.bo.UserUpdateBO;
import com.top.art.converter.UserInfoConverter;
import com.top.art.entity.UserCourse;
import com.top.art.entity.UserInfo;
import com.top.art.entity.UserProvince;
import com.top.art.exception.ArtException;
import com.top.art.service.IUserCourseService;
import com.top.art.service.IUserInfoService;
import com.top.art.service.IUserProvinceService;
import com.top.art.tool.AuthTool;
import com.top.art.vo.AccountInfoVO;
import com.top.art.vo.UserInfoVO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * The type User info manager.
 *
 * @author hjh
 * @version 2020 /10/4-19:23
 */
@Component
public class UserInfoManager {


    /**
     * user info
     */
    @Autowired
    private IUserInfoService userInfoService;

    /**
     * converter
     */
    @Resource
    private UserInfoConverter userInfoConverter;

    /**
     * service
     */
    @Autowired
    private IUserCourseService userCourseService;

    /**
     * service
     */
    @Autowired
    private IUserProvinceService userProvinceService;

    /**
     * Create boolean.
     *
     * @param bo the bo
     * @param account the account
     * @return the boolean
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean create(UserBO bo, AccountInfoVO account) {
        int count = userInfoService.count(Wrappers.<UserInfo>lambdaQuery().eq(UserInfo::getAccount, bo.getAccount()));
        if (count != 0) {
            throw new ArtException(590, "用户账号已存在");
        }
        UserInfo userInfo = userInfoConverter.bo2do(bo);
        userInfo.setCreator(account.getAccount());
        userInfo.setModifier(account.getAccount());
        boolean result1 = userInfoService.save(userInfo);
        if (result1 && CollectionUtils.isNotEmpty(bo.getCourses())) {
            result1 = userCourseService.saveBatch(bo.getCourses().stream().map(x -> {
                UserCourse course = new UserCourse();
                course.setAccount(bo.getAccount());
                course.setCourse(x);
                return course;
            }).collect(Collectors.toList()));
        }
        if (result1 && CollectionUtils.isNotEmpty(bo.getProvinces())) {
            result1 = userProvinceService.saveBatch(bo.getProvinces().stream().map(x -> {
                UserProvince course = new UserProvince();
                course.setAccount(bo.getAccount());
                course.setCreator(account.getAccount());
                course.setProvince(x);
                return course;
            }).collect(Collectors.toList()));
        }
        return result1;
    }

    /**
     * Page page.
     *
     * @param bo the bo
     * @return the page
     */
    public Page<UserInfoVO> page(UserPageQueryBO bo) {
        Page<UserInfoVO> page = new Page<>(bo.getCurrent(), bo.getSize());
        List<String> accountIds = Lists.newArrayList();
        if (StringUtils.isNotBlank(bo.getProvince())) {
            accountIds = userProvinceService.list(Wrappers.<UserProvince>lambdaQuery().eq(UserProvince::getProvince, bo.getProvince()))
                    .stream().map(UserProvince::getAccount).collect(Collectors.toList());
        }
        bo.setAccountIds(accountIds);
        IPage<UserInfo> infoIPage = userInfoService.page(bo);
        page.setTotal(infoIPage.getTotal());
        page.setRecords(infoIPage.getRecords().stream().map(x -> {
            UserInfoVO vo = userInfoConverter.do2userVO(x);
            vo.setProvince(String.join(",", userProvinceService.list(Wrappers.<UserProvince>lambdaQuery()
                    .eq(UserProvince::getAccount, x.getAccount()).select(UserProvince::getProvince))
                    .stream().map(UserProvince::getProvince).collect(Collectors.toList())));
            return vo;
        }).collect(Collectors.toList()));
        return page;
    }

    /**
     * Update boolean.
     *
     * @param bo the bo
     * @return the boolean
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean update(UserUpdateBO bo) {
        AccountInfoVO account = AuthTool.currentUser();
        UserInfo old = userInfoService.getById(bo.getId());
        if (old == null) {
            throw ArtException.buildException("用户不存在");
        }
        UserInfo userInfo = userInfoConverter.bo2do(bo);
        userInfo.setModifier(account.getAccount());
        boolean result = userInfoService.updateById(userInfo);
        userCourseService.remove(Wrappers.<UserCourse>lambdaQuery().eq(UserCourse::getAccount, old.getAccount()));
        userProvinceService.remove(Wrappers.<UserProvince>lambdaQuery().eq(UserProvince::getAccount, old.getAccount()));
        if (result && CollectionUtils.isNotEmpty(bo.getCourses())) {
            result = userCourseService.saveBatch(bo.getCourses().stream().map(x -> {
                UserCourse course = new UserCourse();
                course.setAccount(old.getAccount());
                course.setCourse(x);
                return course;
            }).collect(Collectors.toList()));
        }
        if (result && CollectionUtils.isNotEmpty(bo.getProvinces())) {
            result = userProvinceService.saveBatch(bo.getProvinces().stream().map(x -> {
                UserProvince course = new UserProvince();
                course.setAccount(old.getAccount());
                course.setProvince(x);
                return course;
            }).collect(Collectors.toList()));
        }
        return result;
    }
}
